package com.gzc.just.play.last.war.robotclient;

import com.gzc.just.play.last.war.common.scanner.MessageHandlerScanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 机器人客户端
 * 基于C++ Robot类实现
 * 使用NettyRobotClient进行实际的网络通信
 */
public class RobotClient {
    private static final Logger logger = LoggerFactory.getLogger(RobotClient.class);
    
    // 基本属性
    private final long robotId;
    private final String username;
    private final String password;
    private final String nickname;
    
    // 网络客户端
    private NettyRobotClient nettyClient;
    
    // 状态
    private final AtomicBoolean connected = new AtomicBoolean(false);
    private final AtomicLong lastHeartbeatTime = new AtomicLong(0);
    private final AtomicLong loginTime = new AtomicLong(0);
    
    // 统计信息
    private final AtomicLong messageCount = new AtomicLong(0);
    private final AtomicLong sendCount = new AtomicLong(0);
    private final AtomicLong recvCount = new AtomicLong(0);
    
    private final MessageHandlerScanner messageHandlerScanner;

    public RobotClient(long robotId, String username, String password, String nickname, MessageHandlerScanner messageHandlerScanner) {
        this.robotId = robotId;
        this.username = username;
        this.password = password;
        this.nickname = nickname;
        this.messageHandlerScanner = messageHandlerScanner;
        
        logger.info("Robot client created: id={}, username={}", robotId, username);
    }
    
    /**
     * 连接到服务器
     */
    public boolean connect(String host, int port) {
        try {
            logger.info("Robot {} connecting to {}:{}", robotId, host, port);
            
            // 创建Netty客户端配置
            RobotClientConfig config = new RobotClientConfig();
            config.setRobotId(robotId);
            config.setUsername(username);
            config.setPassword(password);
            config.setNickname(nickname);
            config.setLoginServerHost(host);
            config.setLoginServerPort(port);
            
            // 创建Netty客户端
            nettyClient = new NettyRobotClient(config, messageHandlerScanner);
            
            // 连接到服务器
            boolean success = nettyClient.connectToLoginServer(host, port).get();
            
            if (success) {
                connected.set(true);
                loginTime.set(System.currentTimeMillis());
                lastHeartbeatTime.set(System.currentTimeMillis());
                
                // 启动心跳
                nettyClient.startHeartbeat();
                
                logger.info("Robot {} connected successfully", robotId);
                return true;
            } else {
                logger.error("Robot {} failed to connect", robotId);
                return false;
            }
        } catch (Exception e) {
            logger.error("Robot {} failed to connect: {}", robotId, e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 断开连接
     */
    public void disconnect() {
        try {
            logger.info("Robot {} disconnecting", robotId);
            
            connected.set(false);
            
            if (nettyClient != null) {
                nettyClient.disconnect();
                nettyClient = null;
            }
            
            logger.info("Robot {} disconnected successfully", robotId);
        } catch (Exception e) {
            logger.error("Robot {} failed to disconnect: {}", robotId, e.getMessage(), e);
        }
    }
    
    /**
     * 发送消息
     */
    public boolean sendMessage(byte[] message) {
        if (!connected.get() || nettyClient == null) {
            logger.warn("Robot {} not connected, cannot send message", robotId);
            return false;
        }
        
        try {
            // 解析消息ID
            if (message.length < 4) {
                logger.warn("Robot {} message too short, cannot send", robotId);
                return false;
            }
            
            int messageId = ((message[0] & 0xFF) << 24) |
                           ((message[1] & 0xFF) << 16) |
                           ((message[2] & 0xFF) << 8) |
                           (message[3] & 0xFF);
            
            // 提取消息内容（跳过消息头4字节）
            byte[] messageContent = new byte[message.length - 4];
            System.arraycopy(message, 4, messageContent, 0, messageContent.length);
            
            // 通过Netty客户端发送消息
            nettyClient.sendMessage(messageId, messageContent).get();
            sendCount.incrementAndGet();
            
            logger.debug("Robot {} sent message: {} bytes, ID: {}", robotId, message.length, messageId);
            return true;
        } catch (Exception e) {
            logger.error("Robot {} failed to send message: {}", robotId, e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 发送心跳
     */
    public boolean sendHeartbeat() {
        if (!connected.get() || nettyClient == null) {
            return false;
        }
        
        try {
            // 心跳消息
            byte[] heartbeatMessage = new byte[4];
            heartbeatMessage[0] = 0; // 消息ID高位
            heartbeatMessage[1] = 0;
            heartbeatMessage[2] = (byte) 3; // 心跳消息ID = 1002
            heartbeatMessage[3] = (byte) 234;
            
            // 通过Netty客户端发送心跳
            nettyClient.sendMessage(1002, "heartbeat".getBytes()).get();
            lastHeartbeatTime.set(System.currentTimeMillis());
            
            logger.debug("Robot {} sent heartbeat", robotId);
            return true;
        } catch (Exception e) {
            logger.error("Robot {} failed to send heartbeat: {}", robotId, e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 处理接收到的消息
     */
    public void onMessageReceived(byte[] message) {
        try {
            recvCount.incrementAndGet();
            lastHeartbeatTime.set(System.currentTimeMillis());
            
            logger.debug("Robot {} received message: {} bytes", robotId, message.length);
            
            // 简单的消息处理逻辑
            if (message.length < 4) {
                logger.warn("Robot {} received invalid message, too short", robotId);
                return;
            }
            
            int messageId = ((message[0] & 0xFF) << 24) |
                           ((message[1] & 0xFF) << 16) |
                           ((message[2] & 0xFF) << 8) |
                           (message[3] & 0xFF);
            
            switch (messageId) {
                case 1: // 登录响应
                    logger.info("Robot {} received login response", robotId);
                    break;
                case 2: // 心跳响应
                    logger.debug("Robot {} received heartbeat response", robotId);
                    break;
                default:
                    logger.debug("Robot {} received unknown message: {}", robotId, messageId);
                    break;
            }
        } catch (Exception e) {
            logger.error("Robot {} failed to process message: {}", robotId, e.getMessage(), e);
        }
    }
    
    // Getters
    public long getRobotId() {
        return robotId;
    }
    
    public String getUsername() {
        return username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public String getNickname() {
        return nickname;
    }
    
    public boolean isConnected() {
        return connected.get();
    }
    
    public long getLastHeartbeatTime() {
        // 如果有Netty客户端，优先使用Netty客户端的心跳时间
        if (nettyClient != null) {
            return nettyClient.getLastHeartbeatTime();
        }
        return lastHeartbeatTime.get();
    }
    
    public long getLoginTime() {
        return loginTime.get();
    }
    
    public long getMessageCount() {
        // 如果有Netty客户端，优先使用Netty客户端的消息计数
        if (nettyClient != null) {
            return nettyClient.getMessageCount();
        }
        return messageCount.get();
    }
    
    public long getSendCount() {
        // 如果有Netty客户端，优先使用Netty客户端的发送计数
        if (nettyClient != null) {
            return nettyClient.getSendCount();
        }
        return sendCount.get();
    }
    
    public long getRecvCount() {
        // 如果有Netty客户端，优先使用Netty客户端的接收计数
        if (nettyClient != null) {
            return nettyClient.getRecvCount();
        }
        return recvCount.get();
    }
}